/*
描述
考虑一个具有以下特性的的小型微处理器：

每个字有四位。
地址是两个字。 高字在前。 也就是说两个字组成的地址中的高字总是在低字的内存前。
内存占有256个字。
有两个累加器，A和B， 每个存储一个字。
一个有9个指令代码。每个指令需要至少一个字来存储代表这条指令的代码。有四条指令有参数并需要额外的两字。
每个四位代表的数字可以有值0~15，包括0和15在内，10进制。我们会以常见的十六进制的行式编写代码。也就是说A代表10，B代表11……

下面是9条指令：

代 码	字数
描述

0	3	LD：装载指令中参数代表的地址的内容到累加器A
1	3	ST：向指令中参数代表的地址写入累加器A的内容
2	1	SWP：交换A和B的内容
3	1	ADD：将A和B中的内容相加，并将结果的低字写入A，高字写入B
4	1	INC：A中数加1，允许向上溢出，也就是说F + 1-->0
5	1	DEC：A中数减1，允许向下溢出，也就是说0 - 1-->F
6	3	BZ：如果A = 0，下一个要执行的命令是在参数代表的地址的指令；如果A不是0，则参数被忽略不执行。
7	3	BR：下一条要执行的指令在参数指定的地址。
8	1	STP：程序中止执行。
微处理器每次都从00处的代码开始执行，并一直执行直到遇到中止的命令。

以下的例子表现了部分的程序并描述了它们的功效。

程序	描述
01A8	将在1A（10进制26）处的内容装入A，并终止。
01A512F8	将在1A（10进制26）处的内容装入A，A减1，把结果保存在2F处，并终止。
输入
在输入中将包含由正好256个字符组成的数行。每一行都代表内存的内容，地址00到FF。

如果一行代码的00处是8，程序结束输入。程序运行的过程中不会从内存中溢出，也就是说不会有F0到FF的指令让你去执行。

输出
对于给出的每一种内存状况，你必须从00开始模拟执行，当遇到停止命令时，将当时的内存中的内容输出成一行256个字符的串（由16进制表示）。
*/

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#if defined(_WIN32) && !defined(__cplusplus)
#define inline __inline
#endif

#include <stdio.h>
#include <memory.h>
typedef unsigned char BYTE;
#define MEM_SIZE 256

BYTE GetPara(BYTE wordHigh, BYTE wordLow)
{
	BYTE para = wordHigh * 16 + wordLow;
	return para;
}

int main()
{
	for (;;)
	{
		BYTE acA = 0, acB = 0;
		BYTE mem[MEM_SIZE];

		for (int i = 0; i < MEM_SIZE;i++)
		{
			char ch = getchar();
			if('0' <= ch && ch <= '9')
			{
				mem[i] = ch - 48;
			}
			else if('A' <= ch && ch <= 'F')
			{
				mem[i] = ch - 55;
			}
			else if('a' <= ch && ch <= 'f')
			{
				mem[i] = ch - 87;
			}
		}
		getchar();

		if (mem[0] == 8) break;

		for (int i = 0; i < MEM_SIZE;)
		{
			switch (mem[i])
			{
				// LD：装载指令中参数代表的地址的内容到累加器A
				case 0:
				{
					BYTE para = GetPara(mem[i + 1], mem[i + 2]);
					acA = mem[para];
					i += 3;
					break;
				}
				// ST：向指令中参数代表的地址写入累加器A的内容
				case 1:
				{
					BYTE para = GetPara(mem[i + 1], mem[i + 2]);
					mem[para] = acA;
					i += 3;
					break;
				}
				// SWP：交换A和B的内容
				case 2:
				{
					BYTE temp = acA;
					acA = acB;
					acB = temp;
					++i;
					break;
				}
				// ADD：将A和B中的内容相加，并将结果的低字写入A，高字写入B
				case 3:
				{
					BYTE temp = acA  + acB ;
					acA = temp & 0xF;
					acB = (temp & 0xF0) >> 4;
					++i;
					break;
				}
				// INC：A中数加1，允许向上溢出，也就是说F+1-->0
				case 4:
				{
					++acA;
					if (acA > 0xF) acA = 0;
					++i;
					break;
				}
				// DEC：A中数减1，允许向下溢出，也就是说0-1-->F
				case 5:
				{
					--acA;
					if (acA < 0) acA = 0xF;
					++i;
					break;
				}
				// BZ：如果A=0，下一个要执行的命令是在参数代表的地址的指令；如果A不是0，则参数被忽略不执行。
				case 6:
				{
					BYTE para = GetPara(mem[i + 1], mem[i + 2]);
					if (acA == 0) i = para;
					else i += 3;
					break;
				}
				// BR：下一条要执行的指令在参数指定的地址。
				case 7:
				{
					BYTE para = GetPara(mem[i + 1], mem[i + 2]);
					i = para;
					break;
				}
				// STP：程序中止执行。
				case 8:
				{
					goto end;
				}
			}
		}


	end:
		for (int i = 0; i < MEM_SIZE; i++)
		{
			printf("%X", mem[i]);
		}
		printf("\n");
	}

}